﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
using WorldMapBase.Display;
using WorldMapBase.Tile.Pool;
using WorldMapNew;
using Yoozoo.Libs;
using Yoozoo.Managers;

namespace WorldMapBase.Tile
{
    public class CommandTileElement : IClass
    {
        // ================================ 普通地图元素 ================================
        internal WorldMapNew.TileElement m_Data; //地块元素数据
        // ================================ 装饰物 ================================
        private TilePointAdornData m_adornData;
        private Vector3 m_worldPos;
        internal bool m_isHide;
        private int m_rotation;
        // ================================ 通用 ================================

        private IDisplayCommandInterface m_DisplayCommandInterface;
        private IDisplayElement m_DisplayElement; // 地图块对象
        private int m_ShowCommandID = -1; // 显示命令id

        private Vector3 m_scale; // 缩放值
        private int m_lodIndex; // lod
        internal int m_MapLayer; // 所属层级

        public static CommandTileElement Create(int lodIndex,int mapLayer, WorldMapNew.TileElement tileElementData,Vector3 offset, IDisplayCommandInterface displayCommandInterface)
        {
            CommandTileElement element = ClassPoolManager.GetCommandTileEle();

            element.Initialize(lodIndex,mapLayer,tileElementData, offset, displayCommandInterface);
            return element;
        }

        public static CommandTileElement Create(int mapLayer, TilePointAdornData adornData, Vector3 worldPos, bool hide,
           int rotation, IDisplayCommandInterface displayCommandInterface)
        {
            CommandTileElement element = ClassPoolManager.GetCommandTileEle();

            element.Initialize(mapLayer, adornData, worldPos, hide, rotation, displayCommandInterface);
            return element;
        }

        public void OnReset()
        {
            if (m_DisplayElement != null)
            {
                m_DisplayCommandInterface.AddHideCommand(m_DisplayElement);
                m_DisplayElement = null;
            }
            else
            {
                if (m_ShowCommandID < 0)
                {
                    UnregisterLoadCallBack();
                }
                else
                { 
                    m_DisplayCommandInterface.RemoveCommand(m_ShowCommandID);
                }
            }
            m_ShowCommandID = -1;
        }

        void Initialize(int lodIndex, int mapLayer,WorldMapNew.TileElement tileElementData,Vector3 offset, IDisplayCommandInterface displayCommandInterface)
        {
            m_Data = new TileElement();
            // 本地缓存m_Data 存在缓存 值拷贝
            m_Data.position = tileElementData.position;
            m_Data.rotation = tileElementData.rotation;
            m_Data.scale = tileElementData.scale;
            m_Data.resID = tileElementData.resID;
            m_Data.pointType = tileElementData.pointType;
            // 修正坐标
            m_Data.position += offset;
            m_scale = m_Data.scale;
            m_DisplayCommandInterface = displayCommandInterface;
            m_lodIndex = lodIndex;
            m_MapLayer = mapLayer;
            var resID = m_Data.resID;
            m_DisplayElement = m_DisplayCommandInterface.TryRemoveHideCommandAndGetElement(resID);
            if (m_DisplayElement == null)
            {
                if (m_ShowCommandID < 0)
                { 
                    m_ShowCommandID = m_DisplayCommandInterface.AddShowCommand(lodIndex,mapLayer, resID, this);
                }
            }
            else
            {
                RefreshElementData(mapLayer);
            }
            
        }

        void Initialize(int mapLayer, TilePointAdornData adornData, Vector3 worldPos, bool hide,
                int rotation, IDisplayCommandInterface displayCommandInterface)
        {
            this.m_MapLayer = mapLayer;
            this.m_adornData = adornData;
            this.m_worldPos = worldPos;
            this.m_isHide = hide;
            this.m_rotation = rotation;
            m_DisplayCommandInterface = displayCommandInterface;

            var resID = adornData.resId;
            m_DisplayElement = m_DisplayCommandInterface.TryRemoveHideCommandAndGetElement(resID);
            if (m_DisplayElement == null)
            {
                if (m_ShowCommandID < 0)
                {
                    m_ShowCommandID = m_DisplayCommandInterface.AddShowCommand(1, mapLayer, resID, this);
                }
            }
            else
            {
                RefreshElementData(mapLayer);
            }

        }

        public void SetDisplayElement(IDisplayElement element)
        {
            m_DisplayElement = element;
            m_ShowCommandID = -1;
        }
        
        public void RefreshElementData(int mapLayer)
        {
            if (m_DisplayElement != null)
            {
                // 如果是普通对象
                if (!IsAdorn())
                {
                    m_DisplayElement.SetPosition(m_Data.position);
                    m_DisplayElement.SetRotation(m_Data.rotation);
                    m_DisplayElement.SetScale(m_scale);
                }
                else
                {
                    if (m_isHide)
                    {
                        AdornObject adornObj = m_DisplayElement as AdornObject;
                        adornObj.SetPosition2(m_worldPos);
                    }
                    else
                    {
                        m_DisplayElement.SetPosition(m_worldPos);
                    }
                    if (mapLayer == WorldEntry.ALLIANCEPOINT_ROAD_LAYER_ID || mapLayer == WorldEntry.ALLIANCEPOINT_CROSS_LAYER_ID)
                    {
                        m_DisplayElement.SetRotation(new Vector3(0, m_rotation * 90, 0));
                    }
                    else
                    {
                        m_DisplayElement.SetRotation(new Vector3(0, m_rotation * 90, 0) + m_adornData.rotation);
                    }
                    m_DisplayElement.SetScale(Vector3.one);
                }
              
            }
        }

        public void SetScale(Vector3 scale)
        {
            if (m_DisplayElement != null)
            {
                m_DisplayElement.SetScale(m_scale);
            }
            m_scale = scale;
        }

        /// <summary>
        /// 显示碰撞范围
        /// </summary>
        //public void ShowCollider(bool enabled)
        //{
        //    if (m_DisplayElement is WorldObject worldObject)
        //    {
        //        worldObject.ShowCollider(enabled);
        //    }
        //}

        //public void SetOpenUp(int lodLv, float percent)
        //{
        //    if (m_DisplayElement != null)
        //    {
        //        m_DisplayElement.SetOpenUp(lodLv,percent);
        //    }
        //}

        public bool IsElementRender(List<Vector2> corners)
        {
            bool render = false;
            if (m_DisplayElement != null)
            {
                WorldObject obj = m_DisplayElement as WorldObject;
                if (obj != null)
                {
                    MeshRenderer r = obj.GetRefTrans.GetComponentInChildren<MeshRenderer>();
                    if (r == null) return render;
                    if (r != null) render = r.isVisible && r.gameObject.activeSelf;
                    Vector2 v2 = new Vector2(r.bounds.center.x, r.bounds.center.z);
                    if (render) render = PointInPolygon.isInside(corners, corners.Count, v2);
                }
            }
            return render;
        }

        public bool IsAdorn()
        {
            return m_MapLayer == WorldEntry.ALLIANCEPOINT_CROSS_LAYER_ID ||
                m_MapLayer == WorldEntry.ALLIANCEPOINT_ROAD_LAYER_ID ||
                 m_MapLayer == WorldEntry.MAP_POINT_ADORN_LAYER_ID;
        }

        public void SetPosition(Vector3 pos)
        {
            m_worldPos = pos;
            RefreshElementData(m_MapLayer);
        }

        public int GetResId()
        {
            int resId = -1;
            if (m_adornData != null)
            {
                resId = m_adornData.resId;
            }
            if (m_Data != null)
            {
                resId = m_Data.resID;
            }
            if (m_DisplayElement != null)
            {
                resId = m_DisplayElement.GetResID();
            }
            return resId;
        }

        public int GetRotationInt()
        {
            return m_rotation;
        }

        public void RegisterLoadCallBack()
        {
            WorldPoolManager.RegisterLoadCallBack(GetResId(), this);
        }

        public void UnregisterLoadCallBack()
        {
            WorldPoolManager.UnregisterLoadCallBack(GetResId(), this);
        }

        public void LoadResCallBack(int resId)
        {
            int _resId = GetResId();
            if (m_DisplayElement == null && _resId == resId)
            {
                var element = WorldPoolManager.GetWorldObject(m_lodIndex, m_MapLayer, _resId);
                SetDisplayElement(element);
                RefreshElementData(m_MapLayer);
            }
        }
    }

}
